﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using DefeatEpidemic.Models;
using DefeatEpidemic.Common;
using LinqKit;
using DefeatEpidemic.Base;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.StaticFiles;
using System.IO;

namespace DefeatEpidemic.Controllers
{
    [SignFilter]
    public class ApplicationsController : Controller
    {
        private readonly DefeatEpidemicContext _context;

        public ApplicationsController(DefeatEpidemicContext context)
        {
            _context = context;
        }

        // GET: Applications
        public IActionResult Index()
        {
            return View();
        }
        /// <summary>
        /// 获取申请列表
        /// </summary>
        /// <param name="applicant">申请人</param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <param name="pageindex"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        public  IActionResult GetList(string applicant, DateTime? start, DateTime? end, Guid? member_id, int pageindex = 1, int pagesize = 10)
        {
            Response resp = new Response();
            try
            {
                var where = PredicateBuilder.New<Application>(true);
                if (!string.IsNullOrEmpty(applicant))
                    where.And(u => u.applicant.Contains(applicant));
                if (start != null)
                    where.And(u => u.outTime >= start);
                if (end != null)
                    where.And(u => u.outTime <= end);
                if (member_id != null)
                    where.And(u => u.member.id == member_id);
                int skip = (pageindex - 1) * pagesize;
                var applications =  _context.Applications.Where(where);

                resp.code = 1;
                resp.data = new { items = applications.Skip(skip).Take(pagesize), total = applications.Count() };
            }
            catch (Exception ex)
            {
                resp.code = -1;
                resp.message = $"error:{ex.Message}.{ex.StackTrace}";
            }
            return Json(resp);
        }


        [HttpPost]
        public async Task<IActionResult> Export(string applicant, DateTime? start, DateTime? end, Guid? member_id)
        {
            IExporter exporter = new ExcelExporter();
            var where = PredicateBuilder.New<Application>(true);
            if (!string.IsNullOrEmpty(applicant))
                where.And(u => u.applicant.Contains(applicant));
            if (start != null)
                where.And(u => u.outTime >= start);
            if (end != null)
                where.And(u => u.outTime <= end);
            if (member_id != null)
                where.And(u => u.member.id == member_id);
            var applications = await _context.Applications
                .Where(where)
                .ToListAsync();
            List<RequestModels.ExportApplicationModel> list = new List<RequestModels.ExportApplicationModel>();
            foreach (var application in applications)
            {
                await _context.Entry(application).Reference(d => d.member).LoadAsync();
                int cnt = 1;
                string status = "未审核";
                if (application.status == 1)
                    status = "出门审核通过";
                else if (application.status == 2)
                    status = "进门审核通过";
                else if (application.status == -1)
                    status = "未通过";
                var exportmodel = new RequestModels.ExportApplicationModel()
                {
                    id = cnt,
                    applicant = application.applicant,
                    connect = application.connect,
                    from = application.from,
                    to = application.to,
                    measuredTemp = application.measuredTemp,
                    reason = application.reason,
                    outTime = application.outTime,
                    carNumber = application.carNumber,
                    created_at = application.created_at,
                    selfTemp = application.selfTemp,
                    status = status,
                    isDirve=application.isDirve                    
                };
                list.Add(exportmodel);
                cnt++;
            }
            string path = $@"export\{DateTime.Now.ToString("yyyyMMdd")}";
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            string filename = Path.Combine(path, "社区人员出入申请列表_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx");
            var result = await exporter.Export(filename, list);
            var provider = new FileExtensionContentTypeProvider();
            FileInfo fileInfo = new FileInfo(filename);
            var ext = fileInfo.Extension;
            new FileExtensionContentTypeProvider().Mappings.TryGetValue(ext, out var contenttype);
            return File(System.IO.File.ReadAllBytes(filename), contenttype ?? "application/octet-stream", fileInfo.Name);
        }
        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="status"></param>
        /// <param name="apply_id"></param>
        /// <returns></returns>
        [ValidateAntiForgeryToken]
        [HttpPost]
        public async Task<IActionResult> Check(int status, Guid apply_id)
        {
            Response resp = new Response();
            try
            {
                var app = await _context.Applications.FindAsync(apply_id);
                if (app.status == 2)
                {
                    resp.message = "该申请已结束";
                    return Json(resp);
                }
                string message = "";
                if (app.status == 0)
                {
                    app.status = status;
                    message = "出门审核成功";
                }
                else if (app.status == 1 && status == 1)
                {
                    app.status = 2;
                    message = "进门审核成功";
                }
                else
                    app.status = status;
                app.remark = "后台审核";
                app.outTime = DateTime.Now;
                _context.Update(app);
                int ret = await _context.SaveChangesAsync();
                if (ret > 0)
                {
                    resp.code = 1;
                    resp.message = message;
                }
            }
            catch (Exception ex)
            {
                resp.code = -1;
                resp.message = $"error:{ex.Message}";
            }
            return Json(resp);
        }
        // GET: Applications/Details/5
        public async Task<IActionResult> Details(Guid? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var application = await _context.Applications
                .FirstOrDefaultAsync(m => m.id == id);
            if (application == null)
            {
                return NotFound();
            }

            return View(application);
        }

        // GET: Applications/Create
        public IActionResult Create()
        {
            return View();
        }

        /// <summary>
        /// 获取申请人信息
        /// </summary>
        /// <param name="member_id"></param>
        /// <returns></returns>
        public async Task<IActionResult> GetApplicatInfo(Guid member_id)
        {
            Response resp = new Response();
            try
            {
                var member = await _context.Members.FindAsync(member_id);
                resp.code = 1;
                resp.data = member;
            }
            catch (Exception ex)
            {
                resp.code = -1;
                resp.message = $"error:{ex.Message},{ex.StackTrace}";
            }
            return Json(resp);
        }

        // POST: Applications/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("id,applicant,from,to,isDirve,carNumber,outNumber,status,reason,remark,selfTemp,connect")] Application application)
        {
            if (ModelState.IsValid)
            {
                application.id = Guid.NewGuid();
                _context.Add(application);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            return View(application);
        }

        // GET: Applications/Edit/5
        public async Task<IActionResult> Edit(Guid? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var application = await _context.Applications.FindAsync(id);
            if (application == null)
            {
                return NotFound();
            }
            return View(application);
        }

        // POST: Applications/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(Guid id, [Bind("id,applicant,from,to,isDirve,carNumber,outNumber,status,reason,remark")] Application application)
        {
            if (id != application.id)
            {
                return NotFound();
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(application);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ApplicationExists(application.id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(application);
        }

        // GET: Applications/Delete/5
        public async Task<IActionResult> Delete(Guid? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var application = await _context.Applications
                .FirstOrDefaultAsync(m => m.id == id);
            if (application == null)
            {
                return NotFound();
            }

            return View(application);
        }

        // POST: Applications/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(Guid id)
        {
            var application = await _context.Applications.FindAsync(id);
            _context.Applications.Remove(application);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }

        private bool ApplicationExists(Guid id)
        {
            return _context.Applications.Any(e => e.id == id);
        }
    }
}
